package com.yisu.auction.manager.domain.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.*;
import redis.clients.util.SafeEncoder;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;


/**
 * /**
 * User: 赵杰
 * Date: 2017/5/17
 * Time: 13:36
 * Desc: .
 */
public class JedisClusterUtil {
    private static final Logger log = LoggerFactory.getLogger(RedisUtil.class);

    //默认缓存时间
    private static final int EXPIRE = 60000;

    private static Properties properties;

    private static JedisClusterUtil instance;

    private static JedisPool jedisPool;

    private static JedisCluster jedisCluster;


    private static final String IP = "192.168.8.161"; // ip
    private static final int PORT = 4001;         // 端口
    private static final String AUTH = "";          // 密码(原始默认是没有密码)
    private static int MAX_ACTIVE = 1024;       // 最大连接数
    private static int MAX_IDLE = 200;          // 设置最大空闲数
    private static int MAX_WAIT = 10000;        // 最大连接时间
    private static int TIMEOUT = 10000;         // 超时时间
    private static boolean BORROW = true;         //jedis调用borrowObject方法时，是否进行有效检查#
    private static boolean TEST_On_RETURN = true;  //jedis调用returnObject方法时，是否进行有效检查 #

    private static ReentrantLock lock = new ReentrantLock();

    public JedisClusterUtil() {

    }

    public static JedisClusterUtil getInstance() {
        if (instance == null) {
            lock.lock();
            if (instance == null) {
                instance = new JedisClusterUtil();
            }
            lock.unlock();
        }
        return instance;
    }

    /**
     * 初始化JedisPool
     */
    private void initJedisClusterPool() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(MAX_IDLE);
        poolConfig.setTestOnBorrow(BORROW);
        poolConfig.setTestOnReturn(true);
        Set<HostAndPort> nodes = new HashSet<HostAndPort>();
        HostAndPort hostAndPort = new HostAndPort("192.168.8.161", 4001);
        HostAndPort hostAndPort1 = new HostAndPort("192.168.8.161", 4002);
        HostAndPort hostAndPort2 = new HostAndPort("192.168.8.161", 4003);
        nodes.add(hostAndPort);
        nodes.add(hostAndPort1);
        nodes.add(hostAndPort2);
        jedisCluster = new JedisCluster(nodes);//JedisCluster中默认分装好了连接池.
    }
    /**
     * 通用方法：从JedisPool中获取Jedis
     *
     * @return
     */
    private JedisCluster getjedisCluster() {
        initJedisClusterPool();
        return jedisCluster;
    }

    /**
     * 通用方法：释放Jedis
     *
     * @param jedisCluster
     */
    private void closeJedisCluster(JedisCluster jedisCluster) {
        try {
            jedisCluster.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 对Keys,以及存储结构为String、List、Set、HashMap类型的操作
     */
    private final Strings strings = new Strings();
    private final Keys keys = new Keys();

    public Strings strings() {
        return strings;
    }
    public Keys keys() {
        return keys;
    }

    public class Keys {


        /**
         * 清空所有key
         *
         * @return
         */
        public String flushAll() {
            JedisCluster jedisCluster = getjedisCluster();
            String stata = jedisCluster.flushAll();
            closeJedisCluster(jedisCluster);
            return stata;
        }

        /**
         * 判断key是否存在
         *
         * @param key
         * @return boolean
         */
        public boolean exists(String key) {
            JedisCluster jedisCluster = getjedisCluster();
            boolean exis = jedisCluster.exists(key);
            closeJedisCluster(jedisCluster);
            return exis;
        }


        /**
         * 删除keys对应的记录,可以是多个key
         *
         * @param keys
         * @return 删除的记录数
         */
        public long del(String... keys) {
            JedisCluster jedisCluster = getjedisCluster();
            long count = jedisCluster.del(keys);
            closeJedisCluster(jedisCluster);
            return count;
        }

    }

    public class Strings {
        /**
         * 根据key获取记录
         *
         * @param key
         * @return 值
         */
        public String get(String key) {
            JedisCluster jedisCluster = getjedisCluster();
            String value = jedisCluster.get(key);
            closeJedisCluster(jedisCluster);
            return value;
        }



        /**
         * 添加有过期时间的记录
         *
         * @param key
         * @param seconds 过期时间，以秒为单位
         * @param value
         * @return String 操作状态
         */
        public String setEx(String key, int seconds, String value) {
            JedisCluster jedisCluster = getjedisCluster();
            String str = jedisCluster.setex(key, seconds, value);
            closeJedisCluster(jedisCluster);
            return str;
        }


        /**
         * 添加一条记录，仅当给定的key不存在时才插入
         *
         * @param key
         * @param value
         * @return long 状态码，1插入成功且key不存在，0未插入，key存在
         */
        public long setnx(String key, String value) {
            JedisCluster jedisCluster = getjedisCluster();
            long str = jedisCluster.setnx(key, value);
            closeJedisCluster(jedisCluster);
            return str;
        }

        /**
         * 添加记录,如果记录已存在将覆盖原有的value
         *
         * @param key
         * @param value
         * @return 状态码
         */
        public String set(String key, String value) {
            JedisCluster jedisCluster = getjedisCluster();
            String status = jedisCluster.set(key, value);
            closeJedisCluster(jedisCluster);
            return status;
        }

        /**
         * 添加记录,如果记录已存在将覆盖原有的value
         *
         * @param key
         * @param value
         * @return 状态码
         */
        public String set(String key, byte[] value) {
            return set(SafeEncoder.encode(key), value);
        }

        /**
         * 添加记录,如果记录已存在将覆盖原有的value
         *
         * @param key
         * @param value
         * @return 状态码
         */
        public String set(byte[] key, byte[] value) {
            JedisCluster jedisCluster = getjedisCluster();
            String status = jedisCluster.set(key, value);
            closeJedisCluster(jedisCluster);
            return status;
        }

        /**
         * 从指定位置开始插入数据，插入的数据会覆盖指定位置以后的数据<br/>
         * 例:String str1="123456789";<br/>
         * 对str1操作后setRange(key,4,0000)，str1="123400009";
         *
         * @param key
         * @param offset
         * @param value
         * @return long value的长度
         */
        public long setRange(String key, long offset, String value) {
            JedisCluster jedisCluster = getjedisCluster();
            long len = jedisCluster.setrange(key, offset, value);
            closeJedisCluster(jedisCluster);
            return len;
        }

        /**
         * 在指定的key中追加value
         *
         * @param key
         * @param value
         * @return long 追加后value的长度
         **/
        public long append(String key, String value) {
            JedisCluster jedisCluster = getjedisCluster();
            long len = jedisCluster.append(key, value);
            closeJedisCluster(jedisCluster);
            return len;
        }
    }

}
